package com.ygl.connection;

import java.sql.Connection;
import java.sql.DriverManager;
import java.util.List;
import java.util.Vector;

/**
 * @author： ygl
 * @date： 2019/01/29
 * @Description：
 */
public class ConnectionPool implements IConnectionPool {
    // 空闲线程
    private List<Connection> freeConnection = new Vector<Connection>();
    // 活动线程
    private List<Connection> activeConnection = new Vector<Connection>();

    public DbBean dbBean;

    // 连接数
    private int countConnection = 0;

    ConnectionPool(DbBean dbBean){
        this.dbBean = dbBean;
    }

    // 初始化线程池
    private void init() throws Exception{
        if (dbBean == null) {
            throw new Exception("读取数据库配置失败");
        }
        //1.获取初始化连接数
        for (int i = 0; i < dbBean.getInitConnections(); i++) {
            //2.创建Connection连接
            Connection connection = createConnection();
            if (connection != null) {
                //3.存放在freeConnection集合
                freeConnection.add(connection);
            }
        }
    }

    /**
     * 创建连接
     * @return
     */
    private Connection createConnection(){
        try {
            Class.forName(dbBean.getDriveName());
            Connection connection = DriverManager.getConnection(dbBean.getUrl(), dbBean.getUsername(), dbBean.getPassword());
            countConnection++;
            return connection;
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 获取连接
     * @return
     */
    @Override
    public synchronized Connection getConnection() {
        try {
            Connection connection = null;
            // 思考：怎么知道当前创建的连接>最大连接数
            if (countConnection < dbBean.getMaxActiveConnections()) {
                // 小于最大活动连接数
                // 1.判断空闲线程是否有数据
                if (freeConnection.size() > 0) {
                    // 空闲线程有存在连接
                    // ==freeConnection.get(0);freeConnection.remove(0)
                    // 拿到在删除
                    connection = freeConnection.remove(0);
                } else {
                    // 创建新的连接
                    connection = createConnection();
                }
                // 判断连接是否可用
                boolean available = isAvailable(connection);
                if (available) {
                    // 存放在活动线程池
                    activeConnection.add(connection);
                    countConnection++;
                } else {
                    countConnection--;
                    connection = getConnection();// 怎么使用重试？ 递归算法
                }

            } else {
                // 大于最大活动连接数，进行等待
                wait(dbBean.getConnTimeOut());
                // 重试
                connection = getConnection();
            }
            return connection;
        } catch (Exception e) {
            return null;
        }
    }

    // 判断连接是否可用
    public boolean isAvailable(Connection connection) {
        try {
            if (connection == null || connection.isClosed()) {
                return false;
            }
        } catch (Exception e) {
            // TODO: handle exception
        }
        return true;
    }


    // 释放连接 回收
    public synchronized void releaseConnection(Connection connection) {
        try {
            // 1.判断连接是否可用
            if (isAvailable(connection)) {
                // 2.判断空闲线程是否已满
                if (freeConnection.size() < dbBean.getMaxConnections()) {
                    // 空闲线程没有满
                    freeConnection.add(connection);// 回收连接
                } else {
                    // 空闲线程已经满
                    connection.close();
                }
                activeConnection.remove(connection);
                countConnection--;
                notifyAll();
            }
        } catch (Exception e) {
            // TODO: handle exception
        }
    }
}
